#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2021/5/16 17:18
# @Author  : LiShan
# @Email   : lishan_1997@126.com
# @File    : compar_delay.py
# @Note    : this is note
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd

font = {'family' : 'SimSun',
    'weight' : 'bold',
    'size'  : '16'}
plt.rc('font', **font)
plt.rc('axes',unicode_minus=False)

dqn_record_file = "./txt/test_dqn_record.txt"
fix_record_file = "./txt/test_fix_record.txt"
compar_file = "./txt/compar.txt"
compar_img = "./png/compare_delay.png"
compar_avg_img = "./png/compare_avg_delay.png"
plan_img = "./png/dqn_plan.png"
plan_freq_img = "./png/dqn_plan_freq.png"
delay_hist_img = "./png/delay_hist.png"
delay_freq_img = "./png/delay_freq.png"
delay_box_img = "./png/delay_box.png"
dqn_dealy_img = "./png/plot_dqn_delay.png"

plan_num = 20

if __name__ == '__main__':
    # dqn 延误
    names = ["step", "plan", "delay", "reward", "state"]
    data = pd.read_csv(dqn_record_file, error_bad_lines=False, sep="\t+", names=names, engine="python")
    dqn_delay = list(data["delay"].values)
    dqn_plan = list(data["plan"].values)
    mean_delay = sum(dqn_delay) / len(dqn_delay)
    mean_delay = round(mean_delay, 3)

    # 绘图
    x = np.linspace(0, len(dqn_delay) - 1, len(dqn_delay))
    plt.plot(x, dqn_delay, color='black', marker='D', linestyle='-', linewidth='1.0')
    plt.plot(x, [mean_delay for i in range(len(x))], color='gray', linestyle='--')
    # 设置坐标轴范围
    # plt.xlim([-1, 20])
    # plt.ylim([50, 70])
    # 设置坐标轴刻度
    # plt.xticks(range(0, 20, 1))
    # plt.yticks(np.arange(50, 72, 2))
    # 设置坐标轴名称
    plt.xlabel("仿真步数", fontproperties="SimSun", size=10.5)
    plt.ylabel("平均延误时间(s)", fontproperties="SimSun", size=10.5)
    # 设置网格
    # plt.grid()
    # 设置边框
    # plt.axis('off')
    # 设置图例
    legend = ["delay"]
    plt.legend(legend, loc="best", frameon=False)
    # 设置标题
    # plt.title("The Delay Curve", fontproperties="Times New Roman", size=10.5)
    # 保存图片
    plt.savefig(dqn_dealy_img, dpi=600)
    # 关闭绘图
    plt.close()

    # fix 延误
    names = ["plan", "step", "delay", "reward"]
    data = pd.read_csv(fix_record_file, error_bad_lines=False, sep="\s+", names=names)
    data.sort_values(by='delay', inplace=True)
    fix_plan = list(data["plan"].values)
    fix_delay = list(data["delay"].values)
    fix_min_idx = fix_plan[fix_delay.index(min(fix_delay))]
    fix_max_idx = fix_plan[fix_delay.index(max(fix_delay))]

    # 延误对比
    compar = list(map(lambda x: round((x - mean_delay) / x * 100, 2), fix_delay))
    content = ""
    print("dqn平均延误：{}".format(mean_delay))
    content += "dqn平均延误：{}".format(mean_delay)
    content += "\n"
    print("min-fix平均延误：{}".format(min(fix_delay)))
    content += "min-fix平均延误：{}".format(min(fix_delay))
    content += "\n"
    print("*"*60)
    content += "*"*60
    content += "\n"
    print("方案 %10d %10d %10d %10d %10d" % (fix_plan[0], fix_plan[1], fix_plan[2], fix_plan[3], fix_plan[4]))
    content += "方案 %10d %10d %10d %10d %10d" % (fix_plan[0], fix_plan[1], fix_plan[2], fix_plan[3], fix_plan[4])
    content += "\n"
    print("延误 %10.3f %10.3f %10.3f %10.3f %10.3f" % (fix_delay[0], fix_delay[1], fix_delay[2], fix_delay[3], fix_delay[4]))
    content += "延误 %10.3f %10.3f %10.3f %10.3f %10.3f" % (fix_delay[0], fix_delay[1], fix_delay[2], fix_delay[3], fix_delay[4])
    content += "\n"
    print("降低 %9.2f%% %9.2f%% %9.2f%% %9.2f%% %9.2f%%" % (compar[0], compar[1], compar[2], compar[3], compar[4]))
    content += "降低 %9.2f%% %9.2f%% %9.2f%% %9.2f%% %9.2f%%" % (compar[0], compar[1], compar[2], compar[3], compar[4])
    content += "\n"
    print("*" * 60)
    content += "*" * 60
    content += "\n"
    with open(compar_file, 'w') as f:
        f.write(content)

    # 绘图
    names = ["plan", "step", "delay", "reward"]
    data = pd.read_csv(fix_record_file, error_bad_lines=False, sep="\s+", names=names)
    fix_plan = list(data["plan"].values)
    fix_delay = list(data["delay"].values)
    compar = list(map(lambda x: round((x - mean_delay) / x * 100, 2), fix_delay))
    x = np.linspace(0, len(compar) - 1, len(compar))
    plt.plot(x, fix_delay, color='gray', marker='D', linestyle='-')
    plt.plot(x, [mean_delay for i in range(len(fix_plan))] , color='gray', marker='*', linestyle='--')

    for i in range(len(x)):
        plt.text(i, fix_delay[i] + 0.2, str(round(compar[i], 2)) + '%', ha='center',
                 fontproperties="Times New Roman", size=5.5)
    # 设置坐标轴范围
    plt.xlim([-1, 20])
    # plt.ylim([35, 80])
    # 设置坐标轴刻度
    plt.xticks(range(0, 20, 1))
    # plt.yticks(np.arange(35, 85, 5))
    # 设置坐标轴名称
    # plt.xlabel("Step", fontproperties="Times New Roman", size=10.5)
    # plt.ylabel("Delay", fontproperties="Times New Roman", size=10.5)
    plt.xlabel("配时方案", fontproperties="SimSun", size=10.5)
    plt.ylabel("延误对比", fontproperties="SimSun", size=10.5)
    # 设置网格
    # plt.grid()
    # 设置图例
    # legend = ["Fix dalay", "DQN dalay", "Fix mean dalay", "DQN mean dalay"]
    legend = ["Fix Dalay", "DQN Dalay"]
    plt.legend(legend, loc="best", frameon=False)
    # 设置标题
    # plt.title("The Delay Curve", fontproperties="Times New Roman", size=10.5)
    # 保存图片
    plt.savefig(compar_avg_img, dpi=600)
    # 关闭绘图
    plt.close()

    # min-fix 延误
    min_fix_file = fix_record_file[:-4] + '_' + str(fix_min_idx) + '.txt'
    print("读取文件：", min_fix_file)
    names = ["step", "plan", "delay", "reward", "state"]
    data = pd.read_csv(min_fix_file, error_bad_lines=False, sep="\t+", names=names, engine="python")
    fix_min_delay = list(data["delay"].values)

    # max-fix 延误
    max_fix_file = fix_record_file[:-4] + '_' + str(fix_max_idx) + '.txt'
    print("读取文件：", max_fix_file)
    names = ["step", "plan", "delay", "reward", "state"]
    data = pd.read_csv(max_fix_file, error_bad_lines=False, sep="\t+", names=names, engine="python")
    fix_max_delay = list(data["delay"].values)

    """dqn、min-fix、max-fix测试延误图"""
    # 绘图
    x = np.linspace(0, len(dqn_delay) - 1, len(dqn_delay))
    plt.plot(x, fix_max_delay, color='gray', marker='*', linestyle=':')
    plt.plot(x, fix_min_delay, color='gray', marker='o', linestyle=':')
    plt.plot(x, dqn_delay, color='black', marker='D', linestyle='--')
    # plt.plot(x, np.full(len(x), np.mean(fix_min_delay)), color="b")
    # plt.plot(x, np.full(len(x), np.mean(dqn_delay)), color="k")
    # 设置坐标轴范围
    # plt.xlim([-1, 501])
    # plt.ylim([35, 80])
    # 设置坐标轴刻度
    # plt.xticks(range(0, 20, 1))
    # plt.yticks(np.arange(35, 85, 5))
    # 设置坐标轴名称
    # plt.xlabel("Step", fontproperties="Times New Roman", size=10.5)
    # plt.ylabel("Delay", fontproperties="Times New Roman", size=10.5)
    plt.xlabel("测试步长", fontproperties="SimSun", size=10.5)
    plt.ylabel("延误时间(s)", fontproperties="SimSun", size=10.5)
    # 设置网格
    # plt.grid()
    # 设置图例
    # legend = ["Fix dalay", "DQN dalay", "Fix mean dalay", "DQN mean dalay"]
    legend = ["Fix Max Dalay", "Fix Min Dalay", "DQN Dalay"]
    plt.legend(legend, loc="best", frameon=False)
    # 设置标题
    # plt.title("The Delay Curve", fontproperties="Times New Roman", size=10.5)
    # 保存图片
    plt.savefig(compar_img, dpi=600)
    # 关闭绘图
    plt.close()

    """dqn方案散点图"""
    # 绘图
    x = np.linspace(0, len(dqn_plan) - 1, len(dqn_plan))
    plt.scatter(x, dqn_plan, color='black', s=20, marker='o')
    # markerline, stemlines, baseline = plt.stem(x, dqn_plan, linefmt='-', markerfmt='o')
    # plt.setp(markerline, color='k')  # 将棉棒末端设置为黑色
    # plt.setp(stemlines, color='k')   # 将棉棒设置为黑色
    # plt.plot(x, np.full(len(x), np.mean(fix_min_delay)), color="b")
    # plt.plot(x, np.full(len(x), np.mean(dqn_delay)), color="k")
    # 设置坐标轴范围
    # plt.xlim([-1, 501])
    plt.ylim([-1, 20])
    # 设置坐标轴刻度
    # plt.xticks(range(0, 20, 1))
    plt.yticks(np.arange(0, 20, 1))
    # 设置坐标轴名称
    # plt.xlabel("Step", fontproperties="Times New Roman", size=10.5)
    # plt.ylabel("Delay", fontproperties="Times New Roman", size=10.5)
    plt.xlabel("测试步长", fontproperties="SimSun", size=10.5)
    plt.ylabel("配时方案", fontproperties="SimSun", size=10.5)
    # 设置网格
    # plt.grid()
    # 设置图例
    # legend = ["Fix dalay", "DQN dalay", "Fix mean dalay", "DQN mean dalay"]
    # legend = ["DQN Plan"]
    # plt.legend(legend, loc="best", frameon=False)
    # 设置标题
    # plt.title("The Delay Curve", fontproperties="Times New Roman", size=10.5)
    # 保存图片
    plt.savefig(plan_img, dpi=600)
    # 关闭绘图
    plt.close()

    """dqn方案频率直方图"""
    se = pd.Series(dqn_plan)
    countDict = dict(se.value_counts())
    proportitionDict = dict(se.value_counts(normalize=True))
    plan_freq = []
    for i in range(plan_num):
        try:
            plan_freq.append(proportitionDict[i])
        except:
            plan_freq.append(0)
    print("dqn中各方案选择频率", plan_freq)

    # 绘图
    x = np.linspace(0, len(plan_freq) - 1, len(plan_freq))
    plt.bar(x, plan_freq, 0.5, color="gray", edgecolor="k")
    # 设置坐标轴范围
    plt.xlim([-1, 20])
    # plt.ylim([35, 80])
    # 设置坐标轴刻度
    plt.xticks(range(0, 20, 1))
    # plt.yticks(np.arange(35, 85, 5))
    # 设置坐标轴名称
    # plt.xlabel("Step", fontproperties="Times New Roman", size=10.5)
    # plt.ylabel("Delay", fontproperties="Times New Roman", size=10.5)
    plt.xlabel("配时方案", fontproperties="SimSun", size=10.5)
    plt.ylabel("出现频率", fontproperties="SimSun", size=10.5)
    # 设置网格
    # plt.grid()
    # 设置图例
    # legend = ["DQN Plan Frequency"]
    # plt.legend(legend, loc="best", frameon=False)
    # 设置标题
    # plt.title("The Delay Curve", fontproperties="Times New Roman", size=10.5)
    # 保存图片
    plt.savefig(plan_freq_img, dpi=600)
    # 关闭绘图
    plt.close()

    """dqn延误频率直方图(彩图)"""
    # 绘图
    data = [fix_max_delay, fix_min_delay, dqn_delay]
    n, bins, patches = plt.hist(data, bins=10, rwidth=0.8, align='left', color=['r', 'g', 'b'], edgecolor='k')
    # for i in range(len(n)):
    #     plt.text(bins[i], n[i] + 0.3, int(n[i]), ha='center', fontproperties="Times New Roman", fontsize=8.5)
    # 设置坐标轴范围
    # plt.xlim([30, 90])
    # plt.ylim([35, 80])
    # 设置坐标轴刻度
    # plt.xticks(range(30, 95, 5))
    # plt.yticks(np.arange(35, 85, 5))
    # 设置坐标轴名称
    # plt.xlabel("Step", fontproperties="Times New Roman", size=10.5)
    # plt.ylabel("Delay", fontproperties="Times New Roman", size=10.5)
    plt.xlabel("延误时间", fontproperties="SimSun", size=10.5)
    plt.ylabel("出现频率", fontproperties="SimSun", size=10.5)
    # 设置网格
    # plt.grid()
    # 设置图例
    # legend = ["DQN Plan Frequency"]
    # plt.legend(legend, loc="best", frameon=False)
    # 设置标题
    # plt.title("The Delay Curve", fontproperties="Times New Roman", size=10.5)
    # 保存图片
    plt.savefig(delay_hist_img, dpi=600)
    # 关闭绘图
    plt.close()

    """dqn延误频率直方图(黑白)"""
    # # data = [fix_max_delay, fix_min_delay, dqn_delay]
    # se = pd.Series(fix_max_delay)
    # countDict = dict(se.value_counts())
    # proportitionDict = dict(se.value_counts(normalize=True))
    # plan_freq = []
    # for i in range(plan_num):
    #     try:
    #         plan_freq.append(proportitionDict[i])
    #     except:
    #         plan_freq.append(0)
    # print(plan_freq)

    # 绘图
    data = [fix_max_delay, fix_min_delay, dqn_delay]
    n, bins, _ = plt.hist(data, bins=10)
    y = np.array(n) / np.array(sum(n[0]))
    bins = np.array(bins)
    plt.close()
    x = []
    for i in range(len(bins) - 1):
        x.append((bins[i] + bins[i+1])/2)

    m = np.array(x)
    w = 1.5
    hatch = ['', '///', '...']
    for i in range(len(y)):
        rects = plt.bar(m + w * i, y[i], width=w, color='w', edgecolor='k', hatch=hatch[i])
        # for j in range(0, len(rects)):
        #     rect = rects[j]
        #     height = rect.get_height()
        #     plt.text(rect.get_x() + rect.get_width() / 2, height + 0.3, str(round(height, 3)), ha='center',
        #              fontproperties="Times New Roman", size=5.5)

    # 设置坐标轴范围
    # plt.xlim([30, 90])
    # plt.ylim([35, 80])
    # 设置坐标轴刻度
    # plt.xticks(range(30, 95, 5))
    # plt.yticks(np.arange(35, 85, 5))
    # 设置坐标轴名称
    # plt.xlabel("Step", fontproperties="Times New Roman", size=10.5)
    # plt.ylabel("Delay", fontproperties="Times New Roman", size=10.5)
    plt.xlabel("延误时间", fontproperties="SimSun", size=10.5)
    plt.ylabel("出现频率", fontproperties="SimSun", size=10.5)
    # 设置网格
    # plt.grid()
    # 设置图例
    # legend = ["DQN Plan Frequency"]
    # plt.legend(legend, loc="best", frameon=False)
    # 设置标题
    # plt.title("The Delay Curve", fontproperties="Times New Roman", size=10.5)
    # 保存图片
    plt.savefig(delay_freq_img, dpi=600)
    # 关闭绘图
    plt.close()

    """dqn、fix-min、random、fix-max延误箱型图"""
    plt.figure(figsize=(10, 5))  # 设置画布的尺寸
    # plt.title('Examples of boxplot', fontsize=20)  # 标题，并设定字号大小
    labels = 'fix-max', 'fix-min', 'dqn'  # 图例
    boxprops = dict(linestyle='--', linewidth=3, color='darkgoldenrod')
    flierprops = dict(marker='o', markerfacecolor='green', markersize=12,
                      linestyle='none')
    medianprops = dict(linestyle='-', linewidth=2.5, color='black')
    meanpointprops = dict(marker='D', markeredgecolor='black',
                          markerfacecolor='gray')
    meanlineprops = dict(linestyle='--', linewidth=2.5, color='purple')
    data = [fix_max_delay, fix_min_delay, dqn_delay]
    # vert=False:水平箱线图；showmeans=True：显示均值
    plt.boxplot(data, labels=labels, vert=False, showmeans=True, medianprops=medianprops, meanprops=meanpointprops)
    # plt.boxplot([fix_max_delay, fix_min_delay, dqn_delay], labels=labels, vert=True, showmeans=True)

    for i in range(len(data)):
        mean = np.mean(data[i])
        plt.text(mean, i + 1.2, str(round(float(mean), 3)), ha='center', fontproperties="Times New Roman", size=8.5)

    # 设置坐标轴范围
    # plt.xlim([30, 90])
    # plt.ylim([35, 80])
    # 设置坐标轴刻度
    # plt.xticks(range(30, 95, 5))
    # plt.yticks(np.arange(35, 85, 5))
    # 设置坐标轴名称
    # plt.xlabel("Step", fontproperties="Times New Roman", size=10.5)
    # plt.ylabel("Delay", fontproperties="Times New Roman", size=10.5)
    plt.xlabel("延误时间(s)", fontproperties="SimSun", size=10.5)
    plt.ylabel("配时算法", fontproperties="SimSun", size=10.5)
    # 设置网格
    # plt.grid()
    # 设置图例
    # legend = ["DQN Plan Frequency"]
    # plt.legend(legend, loc="best", frameon=False)
    # 设置标题
    # plt.title("The Delay Curve", fontproperties="Times New Roman", size=10.5)
    # 保存图片
    plt.savefig(delay_box_img, dpi=600)
    # 关闭绘图
    plt.close()

    """dqn、fix-min、fix-max方案延误3D图"""
    # dqn 延误
    names = ["step", "plan", "delay", "reward", "state"]
    data = pd.read_csv(dqn_record_file, error_bad_lines=False, sep="\t+", names=names, engine="python")
    dqn_step = list(data["step"].values)
    dqn_plan = list(data["plan"].values)
    dqn_delay = list(data["delay"].values)
    mean_delay = sum(dqn_delay) / len(dqn_delay)
    mean_delay = round(mean_delay, 3)

    # fix 延误
    names = ["plan", "step", "delay", "reward"]
    data = pd.read_csv(fix_record_file, error_bad_lines=False, sep="\s+", names=names)
    data.sort_values(by='delay', inplace=True)
    fix_plan = list(data["plan"].values)
    fix_delay = list(data["delay"].values)
    fix_min_idx = fix_plan[fix_delay.index(min(fix_delay))]
    fix_max_idx = fix_plan[fix_delay.index(max(fix_delay))]

    # min-fix 延误
    min_fix_file = fix_record_file[:-4] + '_' + str(fix_min_idx) + '.txt'
    print("读取文件：", min_fix_file)
    names = ["step", "plan", "delay", "reward", "state"]
    data = pd.read_csv(min_fix_file, error_bad_lines=False, sep="\t+", names=names, engine="python")
    fix_min_step = list(data["step"].values)
    fix_min_plan = list(data["plan"].values)
    fix_min_delay = list(data["delay"].values)

    # max-fix 延误
    max_fix_file = fix_record_file[:-4] + '_' + str(fix_max_idx) + '.txt'
    print("读取文件：", max_fix_file)
    names = ["step", "plan", "delay", "reward", "state"]
    data = pd.read_csv(max_fix_file, error_bad_lines=False, sep="\t+", names=names, engine="python")
    fix_max_step = list(data["step"].values)
    fix_max_plan = list(data["plan"].values)
    fix_max_delay = list(data["delay"].values)

    fig = plt.figure()
    ax = fig.add_subplot(projection='3d')
    # ax.scatter(dqn_step, dqn_plan, dqn_delay, color='black', marker='^')
    # ax.scatter(fix_min_step, fix_min_plan, fix_min_delay, color='gray', marker='o')
    # ax.scatter(fix_max_step, fix_max_plan, fix_max_delay, color='gray', marker='*')

    ax.scatter(dqn_plan, dqn_step, dqn_delay, color='black', marker='^')
    ax.scatter(fix_min_plan, fix_min_step, fix_min_delay, color='gray', marker='o')
    ax.scatter(fix_max_plan, fix_max_step, fix_max_delay, color='gray', marker='*')

    # ax.scatter(dqn_step, dqn_plan, dqn_delay, marker='^')
    # ax.scatter(fix_min_step, fix_min_plan, fix_min_delay, marker='o')

    # 设置坐标轴范围
    ax.set_ylim([-1, 100])
    ax.set_xlim([-1, 20])
    # 设置坐标轴刻度
    ax.set_yticks(range(0, 120, 20))
    ax.set_xticks(np.arange(0, 25, 5))

    plt.tick_params(labelsize=8.5)
    labels = ax.get_xticklabels() + ax.get_yticklabels() + ax.get_zticklabels()
    # print labels
    [label.set_fontname('Times New Roman') for label in labels]

    # ax.set_xlabel("测试步长", fontproperties="SimSun", size=10.5)
    # ax.set_ylabel("配时方案", fontproperties="SimSun", size=10.5)
    # ax.set_zlabel("延误时间", fontproperties="SimSun", size=10.5)

    ax.set_ylabel("Step", fontproperties="Times New Roman", size=8.5)
    ax.set_xlabel("Plan", fontproperties="Times New Roman", size=8.5)
    ax.set_zlabel("Delay", fontproperties="Times New Roman", size=8.5)

    ax.view_init(elev=10, azim=-30)

    plt.savefig("./png/3d.jpg", dpi=600)
    plt.close()

    print("绘图完成...")
